using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Utility.System;

namespace System.Utility.Helper
{
	public class File
	{
		private readonly static object _sync;

		private readonly static char[] InvalidPathChars;

		private readonly static char[] _InvalidChars;

		static File()
		{
			_sync = new object();
			InvalidPathChars = new char[] { '\"', '<', '>', '|', '\0', '\u0001', '\u0002', '\u0003', '\u0004', '\u0005', '\u0006', '\a', '\b', '\t', '\n', '\v', '\f', '\r', '\u000E', '\u000F', '\u0010', '\u0011', '\u0012', '\u0013', '\u0014', '\u0015', '\u0016', '\u0017', '\u0018', '\u0019', '\u001A', '\u001B', '\u001C', '\u001D', '\u001E', '\u001F', '*', '?', ':' };
			_InvalidChars = Path.GetInvalidFileNameChars();
		}

		public File()
		{
		}

		public static string ConnectLinuxPath(string path1, string path2)
		{
			string[] strArrays = new string[] { path1, path2 };
			return ConnectPath('/', strArrays);
		}

		public static string ConnectPath(char separate, params string[] path)
		{
			string empty;
			char[] chrArray;
			if (TypeExtension.IsInvalid(path))
			{
				empty = string.Empty;
			}
			else if ((int)path.Length == 2)
			{
				string str = path[0];
				chrArray = new char[] { separate };
				string str1 = str.TrimEnd(chrArray);
				object obj = separate;
				string str2 = path[1];
				chrArray = new char[] { separate };
				empty = string.Format("{0}{1}{2}", str1, obj, str2.TrimStart(chrArray));
			}
			else if ((int)path.Length != 1)
			{
				StringBuilder stringBuilder = new StringBuilder(32);
				string[] strArrays = path;
				for (int i = 0; i < (int)strArrays.Length; i++)
				{
					string str3 = strArrays[i];
					chrArray = new char[] { separate };
					string str4 = str3.TrimEnd(chrArray);
					chrArray = new char[] { separate };
					stringBuilder.Append(str4.TrimStart(chrArray)).Append(separate);
				}
				string str5 = stringBuilder.ToString();
				chrArray = new char[] { separate };
				empty = str5.TrimEnd(chrArray);
			}
			else
			{
				empty = path[0];
			}
			return empty;
		}

		public static string ConnectPath(params string[] path)
		{
			return ConnectPath('\\', path);
		}

		public static string ConvertLinuxPath(string linuxpath, char validChar = '\u005F')
		{
			string str;
			int num = linuxpath.IndexOfAny(InvalidPathChars);
			str = (num < 0 ? linuxpath.Replace('/', '\\') : ConvertLinuxPath(linuxpath.Replace(linuxpath[num], validChar), '\u005F'));
			return str;
		}

		public static void CreateDirectory(string directoryPath)
		{
			if (!string.IsNullOrEmpty(directoryPath))
			{
				if (!Directory.Exists(directoryPath))
				{
					Executer.TryRunLogExceptioin(() => Directory.CreateDirectory(directoryPath), string.Format("文件夹{0}创建失败", directoryPath));
				}
			}
		}

		public static void CreateFile(string filePath)
		{
			if (!string.IsNullOrEmpty(filePath))
			{
				try
				{
					if (!IO.File.Exists(filePath))
					{
						CreateDirectory(GetFilePath(filePath, '\\'));
						lock (_sync)
						{
							FileStream fileStream = new FileStream(filePath, FileMode.OpenOrCreate);
							try
							{
							}
							finally
							{
								if (fileStream != null)
								{
									((IDisposable)fileStream).Dispose();
								}
							}
						}
					}
				}
				catch (Exception exception)
				{
					throw new Exception("创建文件异常", exception);
				}
			}
		}

		public static void CreateFile(string filePath, byte[] buffer)
		{
			if (!string.IsNullOrEmpty(filePath))
			{
				try
				{
					if (!IO.File.Exists(filePath))
					{
						FileStream fileStream = (new FileInfo(filePath)).Create();
						try
						{
							fileStream.Write(buffer, 0, (int)buffer.Length);
						}
						finally
						{
							if (fileStream != null)
							{
								((IDisposable)fileStream).Dispose();
							}
						}
					}
				}
				catch
				{
				}
			}
		}

		public static void CreateFile(string filePath, string text)
		{
			CreateFile(filePath, text, Encoding.GetEncoding("utf-8"));
		}

		public static void CreateFile(string filePath, string text, Encoding encoding)
		{
			if ((filePath == null ? false : !(filePath == string.Empty)))
			{
				string str = GetFilePath(filePath, '\\');
				if (!Directory.Exists(str))
				{
					Directory.CreateDirectory(str);
				}
				FileStream fileStream = (new FileInfo(filePath)).Create();
				try
				{
					StreamWriter streamWriter = new StreamWriter(fileStream, encoding);
					try
					{
						streamWriter.Write(text);
						streamWriter.Flush();
					}
					finally
					{
						if (streamWriter != null)
						{
							((IDisposable)streamWriter).Dispose();
						}
					}
				}
				finally
				{
					if (fileStream != null)
					{
						((IDisposable)fileStream).Dispose();
					}
				}
			}
		}

		public static string CreateFileDirectory(string filePath)
		{
			string str = GetFilePath(filePath, '\\');
			CreateDirectory(str);
			return str;
		}

		public static void DeleteFile(string filePath)
		{
			if (!TypeExtension.IsInvalid(filePath))
			{
				try
				{
					IO.File.Delete(filePath);
				}
				catch (Exception exception)
				{
					throw new Exception(string.Concat("删除文件异常:", filePath), exception);
				}
			}
		}

		public static byte[] FileToBytes(string filePath, int len = 0, int start = 0)
		{
			byte[] numArray;
			FileStream stream = FileToStream(filePath);
			try
			{
				int num = (stream.Length > (long)2147483647 ? 2147483647 : (int)stream.Length);
				int num1 = (len == 0 ? num : len);
				num1 = (num1 >= num ? num : num1);
				byte[] numArray1 = new byte[num1];
				stream.Read(numArray1, start, num1);
				numArray = numArray1;
			}
			finally
			{
				if (stream != null)
				{
					((IDisposable)stream).Dispose();
				}
			}
			return numArray;
		}

		public static FileStream FileToStream(string path)
		{
			Guard.ArgumentNotNullOrEmpty(path, "path");
			return new FileStream(path, FileMode.Open, FileAccess.Read);
		}

		public static string FileToString(string filePath)
		{
			return FileToString(filePath, Encoding.UTF8);
		}

		public static string FileToString(string filePath, Encoding encoding)
		{
			string end;
			if (IO.File.Exists(filePath))
			{
				try
				{
					StreamReader streamReader = new StreamReader(filePath, encoding);
					try
					{
						end = streamReader.ReadToEnd();
					}
					finally
					{
						if (streamReader != null)
						{
							((IDisposable)streamReader).Dispose();
						}
					}
				}
				catch (Exception exception)
				{
					throw exception;
				}
			}
			else
			{
				end = string.Empty;
			}
			return end;
		}

		public static string FilterInvalidFileName(string oriName)
		{
			string str = Enumerable.Aggregate(((IEnumerable<char>)_InvalidChars), oriName, (string current, char invalidChar) => current.Replace(invalidChar.ToString(), string.Empty));
			return str;
		}

		public static string GetExtension(string filePath)
		{
			Guard.ArgumentNotNullOrEmpty(filePath, "filePath");
			string empty = string.Empty;
			try
			{
				empty = Path.GetExtension(filePath).Replace(".", string.Empty);
			}
			catch (Exception exception)
			{
			}
			return empty;
		}

		public static long GetFileLength(string filepath)
		{
			long length = (long)0;
			FileStream fileStream = new FileStream(filepath, FileMode.Open, FileAccess.Read);
			try
			{
				length = fileStream.Length;
			}
			finally
			{
				if (fileStream != null)
				{
					((IDisposable)fileStream).Dispose();
				}
			}
			return length;
		}

		public static string GetFileName(string source, char separate = '\\')
		{
			string empty;
			if (!TypeExtension.IsInvalid(source))
			{
				source = source.TrimEnd(new char[] { separate });
				int num = source.LastIndexOf(separate);
				empty = (num <= 0 ? source : source.Substring(num + 1, source.Length - num - 1));
			}
			else
			{
				empty = string.Empty;
			}
			return empty;
		}

		public static string GetFilePath(string source, char separate = '\\')
		{
			string empty;
			if (!TypeExtension.IsInvalid(source))
			{
				source = source.TrimEnd(new char[] { separate });
				int num = source.LastIndexOf(separate);
				empty = (num <= 0 ? source : source.Substring(0, num + 1));
			}
			else
			{
				empty = string.Empty;
			}
			return empty;
		}

		public static IList<FileInfo> GetFiles(string folder, string extension)
		{
			return GetFiles(folder, new string[] { extension });
		}

		public static IList<FileInfo> GetFiles(string folder, string[] extensions)
		{
			List<FileInfo> list = Enumerable.ToList((
			    from file in Directory.GetFiles(folder, "*.*", SearchOption.AllDirectories)
			    let extension = Path.GetExtension(file)
			    where (extension == null ? false : Enumerable.Contains(extensions, extension.ToLower()))
			    select new FileInfo(file)));
			return list;
		}

		public static string GetFileSize(string filePath)
		{
			string fileSize;
			Guard.ArgumentNotNullOrEmpty(filePath, "filePath");
			if (IO.File.Exists(filePath))
			{
				FileInfo fileInfo = new FileInfo(filePath);
				fileSize = GetFileSize(fileInfo.Length, "F2");
			}
			else
			{
				fileSize = string.Empty;
			}
			return fileSize;
		}

		public static string GetFileSize(long len, string format = "F2")
		{
			string str;
			if (len > (long)0)
			{
				string str1 = " B";
				double num = (double)len;
				double num1 = 1024;
				if ((double)len >= num1)
				{
					num = (double)len / num1;
					str1 = " KB";
				}
				if (num > num1)
				{
					num /= num1;
					str1 = " MB";
				}
				if (num > num1)
				{
					num /= num1;
					str1 = " GB";
				}
				str = (num - Math.Truncate(num) != 0 ? string.Concat(num.ToString("F2"), str1) : string.Concat(num.ToString("F2"), str1));
			}
			else
			{
				str = "0 KB";
			}
			return str;
		}

		public static string GetFileSize(int len)
		{
			return GetFileSize((long)len, "F2");
		}

		public static string GetLinuxFileName(string source)
		{
			return GetFileName(source, '/');
		}

		public static string GetLinuxFilePath(string source)
		{
			return GetFilePath(source, '/');
		}

		public static string GetPhysicalPath(string relativePath)
		{
			string empty;
			if (!string.IsNullOrEmpty(relativePath))
			{
				relativePath = relativePath.Replace("/", "\\").Replace("~", string.Empty).Replace("~/", string.Empty);
				relativePath = (relativePath.StartsWith("\\") ? relativePath.Substring(1, relativePath.Length - 1) : relativePath);
				string applicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
				empty = Path.Combine(applicationBase, relativePath);
			}
			else
			{
				empty = string.Empty;
			}
			return empty;
		}

		public static bool InputPathIsValid(string path)
		{
			return (!IsPositiveNumber(path) ? false : IsHasUninvalidPathChars(path));
		}

		public static bool IsFileInUsing(string path)
		{
			bool flag = true;
			try
			{
				FileStream fileStream = new FileStream(path, FileMode.Open);
				try
				{
					flag = false;
				}
				finally
				{
					if (fileStream != null)
					{
						((IDisposable)fileStream).Dispose();
					}
				}
			}
			catch
			{
			}
			return flag;
		}

		private static bool IsHasUninvalidPathChars(string path)
		{
			bool flag = !Enumerable.Any(Path.GetInvalidPathChars(), new Func<char, bool>(path.Contains<char>));
			return flag;
		}

		private static bool IsPositiveNumber(string path)
		{
			return Regex.IsMatch(path, "^[a-zA-Z]:\\\\[^\\/\\:\\*\\?\\\"\\<\\>\\|\\,]+$", RegexOptions.IgnoreCase);
		}

		public static bool IsValid(string file)
		{
			bool flag;
			if (TypeExtension.IsInvalid(file))
			{
				flag = false;
			}
			else if (IO.File.Exists(file))
			{
				flag = ((new FileInfo(file)).Length > (long)0 ? true : false);
			}
			else
			{
				flag = false;
			}
			return flag;
		}

		public static bool IsValidDictory(string path)
		{
			return (TypeExtension.IsInvalid(path) ? false : Directory.Exists(path));
		}

		public static void Open(params string[] path)
		{
			if (!TypeExtension.IsInvalid(path))
			{
				string str = ConnectPath(path);
				try
				{
					Process.Start("explorer.exe", str);
				}
				catch (Exception exception)
				{
					throw new Exception(string.Concat("打开文件出现异常:", str), exception);
				}
			}
		}

		public static byte[] ReadFileHead(string filePath, int index = 4)
		{
			byte[] numArray;
			FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
			try
			{
				byte[] numArray1 = new byte[index];
				fileStream.Read(numArray1, 0, index);
				numArray = numArray1;
			}
			finally
			{
				if (fileStream != null)
				{
					((IDisposable)fileStream).Dispose();
				}
			}
			return numArray;
		}

		public static string TryGetExtension(string filename, char splitChar)
		{
			Guard.ArgumentNotNullOrEmpty(filename, "filePath");
			string[] strArrays = filename.Split(new char[] { splitChar });
			string empty = string.Empty;
			if (Enumerable.Any(strArrays))
			{
				empty = Enumerable.Last(strArrays);
			}
			return empty;
		}
	}
}